"""纱线计数
date: 20240418
by: lei.lei.fan.meng@gmail.com
updated: 1. 纱线数量计数
         2. 卷积核卷积方式
         3. 梯度算子
         4. 纱线可能倾斜
         5. 纱线粗细可能变化

date: 20240419
by: lei.lei.fan.meng@gmail.com
updated: 使用灰度值阈值方法统计线的数量
         1. 计算每一行像素中低于阈值的连续像素段的数量
         2. 对所有行的连续像素段的数量取众数
         
"""

import cv2
import numpy as np


max_intensity = 200

def generate_kernel(h=11,w=11,l=3):
    return np.array([[0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0],
            [0,0,0,255,0,0,0]])


def single_process(im):
    h,w = im.shape
    # 横向检测范围
    left_start = 0.1
    left_end = 0.9

    im = im[0:200,int(w*left_start):int(w*left_end)]
    # 对灰度图进行边缘检测
    edges = cv2.Canny(im, 50, 150, apertureSize=3)

    lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=200, minLineLength=80, maxLineGap=30)
    n = 0
    # 绘制检测到的直线
    im = cv2.cvtColor(im, cv2.COLOR_GRAY2RGB)
    if lines is not None:
        print("Detected lines:", len(lines))
        for line in lines:
            n+=1
            x1, y1, x2, y2 = line[0]
            cv2.line(im, (x1, y1), (x2, y2), (0, 255, 0), 1)
    cv2.imwrite('r.jpg',im)
    
    return n


def single_process_1(im):
    h,w = im.shape
    # 横向检测范围
    left_start = 0.1
    left_end = 0.9
    im = im[:,int(w*left_start):int(w*left_end)]
    kernel = generate_kernel()
    kernel_h, kernel_w = kernel.shape
    
    # 纵向采样点
    sample= 10
    
    stride = (1, 1)
    filtered_image = cv2.filter2D(im[:11,:], -1, kernel)
    
    cv2.imshow('Original Image', im)
    cv2.imshow('Filtered Image', filtered_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
def count_zero_segments(row):
    # 计算每一行中0段的数量
    count = 0
    consecutive_zeros = 0
    # print(row)
    for col in range(len(row)):
        if row[col] == 0:  # 当像素值为0时
            consecutive_zeros += 1
        else:  # 当像素值不为0时
            if consecutive_zeros > 0:
                count += 1
            consecutive_zeros = 0
    if consecutive_zeros > 0:  # 处理行末尾连续的0
        count += 1
    return count


def single_process_2(im,left_start,left_end):
    # 主算法
    h,w = im.shape
    # 横向检测范围

    im = im[:,int(w*left_start):int(w*left_end)]
    # print(im[100,:])
    _, binary_image = cv2.threshold(im, 200, 255, cv2.THRESH_BINARY)
    
    binary_image[binary_image < 200] = 0
    # print(binary_image[50,:])
    lines = []
    
    for i in range(h):
        lines.append(count_zero_segments(binary_image[i,:]))
    
    # print(lines)
    unique_values, counts = np.unique(lines, return_counts=True)
    max_count_index = np.argmax(counts)
    mode_value = unique_values[max_count_index]
    return mode_value
    
    
if __name__ == '__main__':
    img_path = './test2.jpg'
    im = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    lines = single_process_2(im,0.4712,0.50537)
    # lines = single_process_2(im,0.1,0.9)
    print(lines)